package org.bluedream.core.module.service.bill.ord;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.commons.collections.map.HashedMap;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.comm.utils.RestResult;
import org.bluedream.core.module.base.BillServiceImpl;
import org.bluedream.core.module.dao.bill.ord.OrdDao;
import org.bluedream.core.module.entity.bill.ord.Ord;
import org.bluedream.core.module.entity.bill.ord.OrdDtl;
import org.bluedream.core.module.entity.goods.Supplier;
import org.bluedream.core.module.entity.warehouse.WareHouse;
import org.bluedream.core.module.service.bill.OddImportService;
import org.bluedream.core.module.service.goods.SupplierService;
import org.bluedream.core.module.service.stock.SkuStockService;
import org.bluedream.core.module.service.warehouse.WareHouseService;
import org.bluedream.core.utils.DictUtil;
import org.bluedream.core.utils.SpringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.sql.Date;
import java.util.Map;

/**
 * @ClassName OrdService
 * @Description TODO
 * @Author foxsand
 * @Data 2021-11-18 15:03
 * @Version
 */
@Service
@DS("master")
@Transactional(
        readOnly = true
)
public class OrdService extends BillServiceImpl<OrdDao, Ord> implements IService<Ord> {
    private static final Logger logger = LoggerFactory.getLogger(OrdService.class);

    @Resource
    private OrdDtlService ordDtlService;

    @Resource
    private SupplierService supplierService;

    @Resource
    private WareHouseService wareHouseService;

    @Resource
    private SkuStockService wareHouseStockService;

    @Resource
    private OddImportService oddImportService;

    @Override
    public Ord getById(Serializable id) {
        if (EmptyUtil.isEmpty(id)){
            return new Ord();
        }
        return super.getById(id);
    }

    public Ord getOrdBill(Ord entity){
        if (!entity.getIsNewRecord()){
            QueryWrapper<Supplier> sqw = new QueryWrapper<>();
            sqw.eq("code" , entity.getSupplierCode());
            entity.setSupplier(supplierService.getOne(sqw));
            QueryWrapper<WareHouse> wqw = new QueryWrapper<>();
            wqw.eq("code" , entity.getWarCode());
            entity.setWareHouse(wareHouseService.getOne(wqw));
        }
        return entity;
    }

    public IPage<Ord> findPage(Ord entity, String... args) {
        Map<String , Object> search = null;
        search = new HashedMap();
        search.put("1;eq" , "1");
        if (EmptyUtil.isNoEmpty(entity.getSupplierCode())
                || EmptyUtil.isNoEmpty(entity.getBillNum())
                || EmptyUtil.isNoEmpty(entity.getGeCheckDate())
                || EmptyUtil.isNoEmpty(entity.getLtCheckDate())
                || EmptyUtil.isNoEmpty(entity.getGeCreateDate())
                || EmptyUtil.isNoEmpty(entity.getLtCreateDate())
        ){
            try {
                if (EmptyUtil.isNoEmpty(entity.getGeCreateDate())){
                    search.put("create_date;ge" , Date.valueOf(entity.getGeCreateDate()));
                }
                if (EmptyUtil.isNoEmpty(entity.getLtCreateDate())){
                    search.put("create_date;lt" , Date.valueOf(entity.getLtCreateDate()));
                }
                if (EmptyUtil.isNoEmpty(entity.getGeCheckDate())){
                    search.put("check_date;ge" , Date.valueOf(entity.getGeCheckDate()));
                }
                if (EmptyUtil.isNoEmpty(entity.getLtCheckDate())){
                    search.put("check_date;lt" , Date.valueOf(entity.getLtCheckDate()));
                }
            }catch (Exception e){
                e.printStackTrace();
                logger.error(e.getMessage());
            }

            if (EmptyUtil.isNoEmpty(entity.getSupplierCode())){
                search.put("supplier_Code;eq" , entity.getSupplierCode());
            }
            if (EmptyUtil.isNoEmpty(entity.getBillNum())){
                search.put("bill_num" , entity.getBillNum());
            }
        }else {
            long limit = entity.getLimit();
            long page = entity.getPage();
            entity = new Ord();
            entity.setLimit(limit);
            entity.setPage(page);
        }
        IPage<Ord> page = super.findPage(entity , search , args);
        return page;
    }

    @Transactional(
            readOnly = false,
            rollbackFor = Exception.class
    )
    public RestResult saveEntity(Ord entity){
        if (entity.getIsNewRecord()){
            OddImportService oddImportService = SpringUtil.getBean(OddImportService.class);
            String billType = DictUtil.getDictValue("sys.bill.type", "采购订单", "");
            String billNum = oddImportService.getNowBillNum(billType);
            entity.setBillNum(billNum);
            entity.setBillType(billType);
            for (OrdDtl body:entity.getOrdDtlList()
            ) {
                body.setBillNum(billNum);
            }
        }
        boolean flag = super.save(entity);
        if (!flag){
            return RestResult.error("数据保存失败！");
        }
        flag = ordDtlService.saveBatch(entity.getOrdDtlList());
        if (!flag){
            return RestResult.error("数据保存失败！");
        }

        String billType = DictUtil.getDictValue("sys.bill.type", "采购订单", "");
        String billNum = entity.getBillNum();
        return oddImportService.save(billType , billNum)?RestResult.ok():RestResult.error("数据保存失败！");
    }

    @Transactional(
            readOnly = false,
            isolation = Isolation.SERIALIZABLE,
            rollbackFor = Exception.class
    )
    public RestResult check(Ord entity){
        entity = this.getById(entity.getId());
        boolean flag = false;
        super.setCheckAttribute(entity);
        flag = super.save(entity);
        if (!flag){
            return RestResult.error("单据记账失败，单号：" + entity.getBillNum());
        }
        return RestResult.ok("单据：" + entity.getBillNum() + "已记账");
    }
}
